/****************************************Copyright (c)*************************
**                               版权所有 (C), 2015-2020, 涂鸦科技
**
**                                 http://www.tuya.com
**
**--------------文件信息-------------------------------------------------------
**文   件   名: protocol.h
**描        述: 下发/上报数据处理函数
**使 用 说 明 :

                  *******非常重要，一定要看哦！！！********

** 1、用户在此文件中实现数据下发/上报功能
** 2、DP的ID/TYPE及数据处理函数都需要用户按照实际定义实现
** 3、当开始某些宏定义后需要用户实现代码的函数内部有#err提示,完成函数后请删除该#err
**
**--------------当前版本修订---------------------------------------------------
** 版    本: v1.0.1
** 日　  期: 2020年2月26日
** 修改人员: 周猛
** 协议版本: v1.1.1
** 描　  述: 1:产品信息新增tp字段和p字段
             2:修改product_info_update函数，新增参数ver来选择是否支持获取产品pid
               将组包格式由JSON格式换成sprintf，以减轻MCU资源压力
             3:增加带传入帧版本的串口数据发送函数wifi_uart_write_frame_ver
             4:在wifi_uart_service函数中，取消了串口数据对帧版本的校验

** 版    本: v1.0.0
** 日　  期: 2019年7月27日
** 修改人员: 陈力恒
** 协议版本: v1.1.1
** 描　  述: 1:gateway通用协议mcu_sdk初版
**-----------------------------------------------------------------------------
******************************************************************************/

#ifndef __PROTOCOL_H_
#define __PROTOCOL_H_

/******************************************************************************
                            用户相关信息配置
******************************************************************************/
/******************************************************************************
                            1:修改产品信息                
******************************************************************************/
//pid信息，服务端自动插入

#define MCU_VER "1.0.0"                                 //用户的软件版本,用于MCU固件升级,MCU升级版本需修改

//配网方式选择,默认为CONFIG_MODE_DEFAULT,只能三选一
#define CONFIG_MODE     CONFIG_MODE_DEFAULT             //默认配网方式
//#define CONFIG_MODE     CONFIG_MODE_LOWPOWER            //低功耗配网方式
//#define CONFIG_MODE     CONFIG_MODE_SPECIAL             //特殊配网方式


//接入的子设备类型,默认为4,只能四选一
//1(zigbee)、2(蓝牙)、3(红外)只对涂鸦内部自研产品有效，外部用户只可以选4(其他)
//#define ACCESS_SUBDEV_TYPE   1        //zigbee
//#define ACCESS_SUBDEV_TYPE   2        //蓝牙
//#define ACCESS_SUBDEV_TYPE   3        //红外
#define ACCESS_SUBDEV_TYPE   4        //其他

#define PRODUCT_KEY            "uiukq4fmwdyjnffv"

#pragma anon_unions

#pragma pack(1)
typedef union {
    struct{
        unsigned char   local_group            :1;
        unsigned char   local_scene            :1;
        unsigned char   gw_dev                 :1;
        unsigned char   is_sigmesh             :1;
        unsigned char   mcu_ota                :1;
        unsigned char   group_sub              :1;
    	unsigned char   reserved               :2;
    };
    unsigned char whole;
}tSUB_ABILITY;
#pragma pack()

//PACKAGE_SIZE:升级包大小选择
//0x00：默认 256byte
//0x01：512byte 
//0x02：1024byte
#define PACKAGE_SIZE                     0      //默认 256byte
//#define PACKAGE_SIZE                   1      //512byte
//#define PACKAGE_SIZE                   2      //1024byte

#pragma pack(1)
typedef struct {
    unsigned char  len;
    char           id[32];
}tSUB_NODE;

/*子设备列表结构体*/
typedef struct {
    unsigned char  idx              :7; //包序号，从0开始
    unsigned char  sub_package      :1; //false：所有子设备地址发送完成                true：后续仍有子设备地址
    unsigned char  num;                 //下面的sub_list的子设备数量
    tSUB_NODE      sub_list[32];         //子设备列表，可根据实际情况定义大小
}tSUB_LIST;

typedef struct {
    unsigned char    num;       //可用节点数
    unsigned char    id_len;    //一个node的长度(固定为2字节)
    unsigned short   node_id[32];//存放节点的数组，可根据实际情况定义大小
}tSIG_NODE_LIST;

typedef struct{
    unsigned char    id_len; //固定为2
    unsigned short   node;
}tSIG_NODE;
#pragma pack()

/******************************************************************************
                          2:MCU是否需要支固件或者子设备升级
如需要支持MCU固件升级或者是子设备升级,请开启该宏
                        ********WARNING!!!**********
如需要开启该功能,串口接收缓冲区会变大

mcu升级说明：
mcu升级类型分为四种
1. app 提醒升级：这个升级方式用户每次进入设备控制面板都会收到升级提醒的弹窗，
是否确认升级由用户自己在 APP 确认
2. app 静默升级：这个升级方式 app 不会有任何提醒弹窗，固件上电后一分钟内会去
自动去检测升级发现有高版本的升级包会自动开始拉取相关升级包，第一次上电后模块
会间隔 24 小时去云端检测一次是否有升级包配置。
3. app 强制升级: 这个升级方式 app 端会有升级提醒弹窗，如果用户不确认升级用户
就没法正常使用这个产品的控制面板。
4. app 检测升级:这个升级方式 app 端不会有任何升级提醒的弹窗，必须要用户在 app
端自己去点击相关固件版本检测，如果有高版本的固件配置才会显示升级提示信息。

WIFI 模块发送完所有的升级包，重新发送 01 命令字（3.2 查询产品信息）MCU 需要在
一分钟回复产品信息中的软件版本号带上升级后的 MCU 版本号，版本号需要和在涂鸦后台
配置升级的版本号保持一致。
******************************************************************************/
//#define         SUPPORT_MCU_FIRM_UPDATE                 //开启MCU固件升级功能(默认关闭)

/******************************************************************************
                         3:定义收发缓存:
                    用户根据实际情况定义收发缓存的大小
******************************************************************************/
#ifndef SUPPORT_MCU_FIRM_UPDATE
#define WIFI_UART_QUEUE_LMT             128              //数据接收队列大小,用户根据实际情况开大/开小
#define WIFI_UART_RECV_BUF_LMT          128              //根据用户DP数据大小量定,必须大于24
#else
#define WIFI_UART_QUEUE_LMT             128              //数据接收队列大小,用户根据实际情况开大/开小

//当选择升级包单包大小的时候，选择单包256byte，512byte，1024byte，必须要扩大该buf的大小
//固件升级缓冲区,需大缓存
#define WIFI_UART_RECV_BUF_LMT          300              //单包256byte
//#define WIFI_UART_RECV_BUF_LMT          600              //单包512byte
//#define WIFI_UART_RECV_BUF_LMT          1200             //单包1024byte

#endif

#define WIFIR_UART_SEND_BUF_LMT         128              //根据用户DP数据大小量定，用户可根据实际情况修改

/******************************************************************************
                        4:定义模块工作方式
模块自处理:
          wifi指示灯和wifi复位按钮接在wifi模块上(开启WIFI_CONTROL_SELF_MODE宏)
          并正确定义WF_STATE_KEY和WF_RESET_KEY
MCU自处理:
          wifi指示灯和wifi复位按钮接在MCU上(关闭WIFI_CONTROL_SELF_MODE宏)
          MCU在需要处理复位wifi的地方调用mcu_api.c文件内的mcu_reset_wifi()函数,并可调用mcu_get_reset_wifi_flag()函数返回复位wifi结果
          或调用设置wifi模式mcu_api.c文件内的mcu_set_wifi_mode(WIFI_CONFIG_E mode)函数,并可调用mcu_get_wifi_work_state()函数返回设置wifi结果
******************************************************************************/
//#define         WIFI_CONTROL_SELF_MODE                       //wifi自处理按键及LED指示灯;如为MCU外界按键/LED指示灯请关闭该宏
//例如：PORT为2，pin为3则代表选择GPIO C_3
#ifdef          WIFI_CONTROL_SELF_MODE                      //模块自处理
  #define     WF_LED_PORT            2                     //wifi状态指示灯的PORT（prot选择范围：0~3[依次代表A到D]），请根据实际GPIO管脚设置
  #define     WF_LED_PIN             5                     //wifi状态指示灯的PIN（prot选择范围：0~7），请根据实际GPIO管脚设置
  #define     WF_RESERT_KEY_PORT     2                     //重置按键的PORT（prot选择范围：0~3[依次代表A到D]），请根据实际GPIO管脚设置
  #define     WF_RESERT_KEY_PIN      4                     //重置按键的PIN（prot选择范围：0~7），请根据实际GPIO管脚设置
#endif

/******************************************************************************
                      5:MCU是否需要支持校时功能                     
如需要请开启该宏,并在Protocol.c文件内mcu_write_rtctime实现代码
mcu_write_rtctime内部有#err提示,完成函数后请删除该#err
mcu在wifi模块正确联网后可调用mcu_get_system_time()函数发起校时功能
******************************************************************************/
#define         SUPPORT_MCU_RTC_CHECK                //开启校时功能

/******************************************************************************
                      6:MCU是否需要支持获取格林时间功能                 
如需要请开启该宏,并在Protocol.c文件内mcu_get_greentime实现代码
mcu_get_greentime内部有#err提示,完成函数后请删除该#err
mcu在wifi模块正确联网后可调用mcu_get_green_time()函数发起校时功能
******************************************************************************/
#define         SUPPORT_GREEN_TIME                //开启格林时间功能

/******************************************************************************
                      7:MCU是否需要支持wifi功能测试                     
如需要请开启该宏,并且mcu在需要wifi功能测试处调用mcu_api.c文件内mcu_start_wifitest
并在protocol.c文件wifi_test_result函数内查看测试结果,
wifi_test_result内部有#err提示,完成函数后请删除该#err
******************************************************************************/
#define         WIFI_TEST_ENABLE                //开启WIFI产测功能（扫描指定路由）




/******************************************************************************
                        1:网关的dp数据点序列号重新定义
          **此为自动生成代码,如在开发平台有相关修改请重新下载MCU_SDK**         
******************************************************************************/



/*****************************************************************************
函数名称 : all_data_update
功能描述 : 系统所有dp点信息上传
输入参数 : 无
返回参数 : 无
使用说明 : MCU必须实现该函数内数据上报功能
*****************************************************************************/
void all_data_update(void);

#ifdef SUPPORT_GREEN_TIME
/*****************************************************************************
函数名称 : mcu_get_greentime
功能描述 : 获取到的格林时间
输入参数 : 无
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
void mcu_get_greentime(unsigned char time[]);
#endif

#ifdef SUPPORT_MCU_RTC_CHECK
/*****************************************************************************
函数名称 : mcu_write_rtctime
功能描述 : MCU校对本地RTC时钟
输入参数 : 无
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
void mcu_write_rtctime(unsigned char time[]);
#endif

/*****************************************************************************
函数名称 : subdevice_add_result
功能描述 : wifi模块是否接收子设备入网请求结果通知（子设备是否实
           际入网成功需要查看ADD_DEV_RESULT_CMD命令子相关的命令）
输入参数 : result:模块是否接收子设备入网请求结果;0:接收请求/1:拒绝请求
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
void subdevice_add_result(unsigned char result);

/*****************************************************************************
函数名称 : heart_beat_check 
功能描述 : wifi模块WIFI 模组定时（1-3 分钟）检测子设备在线状态。
输入参数 : data_buf：接收到的data部分的首地址
           data_len：接收到的data部分的长度
返回参数 : 无
使用说明 : MCU需要自行调用接口实现该功能
*****************************************************************************/
void heart_beat_check(unsigned char* data_buf,unsigned short data_len);

/*****************************************************************************
函数名称 : batch_add_dev_result
功能描述 :批量添加同一个pid的多个子设备请求结果通知
输入参数 : result:模块是否接收子设备添加请求结果;0:接收请求/1:拒绝请求
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
void batch_add_dev_result(unsigned char result);

/*****************************************************************************
函数名称 : group_subdev_delete
功能描述 : 设备添加完成后，通知 MCU 添加结果
输入参数 : data_buf：接收到的data部分的首地址
           data_len：接收到的data部分的长度
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
void add_dev_result_get(unsigned char* data_buf,unsigned short data_len);

/*****************************************************************************
函数名称 : wifi_status_result
功能描述 : 获取 WIFI 状态结果
输入参数 : result:指示 WIFI 工作状态
           0x00:wifi状态 1 smartconfig 配置状态
           0x01:wifi状态 2 AP 配置状态
           0x02:wifi状态 3 WIFI 已配置但未连上路由器
           0x03:wifi状态 4 WIFI 已配置且连上路由器
           0x04:wifi状态 5 已连上路由器且连接到云端
           0x05:wifi状态 6 WIFI 设备处于低功耗模式
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
void wifi_status_result(unsigned char result);

/*****************************************************************************
函数名称 : inform_dev_del_status
功能描述 : 1 网关收到移除或者恢复出厂命令时，会向 MCU 报告状态。
           2 如果仅收到移除指令，网关只会移除配网，并不会删除子设备信息。
           下次联网时，子设备信息仍会在 app 上显示。
           3 如果收到恢复出厂指令，网关会移除配网并且清除所有子设备信息。
           
输入参数 : result:移除方式
           0x00 本地恢复出厂
           0x01 远程移除
           0x02 本地移除
           0x03 远程恢复出厂
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
void inform_dev_del_status(unsigned char result);

/*****************************************************************************
函数名称 : local_del_subdev
功能描述 : 本地删除子设备结果
输入参数 : result:本地子设备删除结果结果;0:成功/1:失败
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
void local_del_subdev(unsigned char result);

/*****************************************************************************
函数名称 : local_subdev_limit
功能描述 : 本地允许/关闭添加子设备
输入参数 : result:
           0：本地允许/关闭添加子设备成功
           1：本地允许/关闭添加子设备失败
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
void local_subdev_limit(unsigned char result);

/*****************************************************************************
函数名称 : remain_memory_result
功能描述 : 获取模块内存
输入参数 : module_memory:获取模块内存的大小
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
void remain_memory_result(unsigned int module_memory);

/*****************************************************************************
函数名称 : local_subdev_list
功能描述 : 子设备列表
输入参数 : subdev_list_buf：存放子设备的buf
           buf_len：子设备buf的长度
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
void local_subdev_list(unsigned char *subdev_list_buf,unsigned short buf_len);

/*****************************************************************************
函数名称 : upgrade_package_choose
功能描述 : 升级包大小选择
输入参数 : package_sz:升级包大小
           0x00：默认 256byte
           0x01：512byte 
           0x02：1024byte

返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
void upgrade_package_choose(unsigned char package_sz);

/*****************************************************************************
函数名称 : subdev_upgrade_package_choose
功能描述 : 升级包大小选择
输入参数 : package_sz:升级包大小
           0x00：默认 256byte
           0x01：512byte 
           0x02：1024byte
           sub_dev_id:子设备id
           sub_dev_len:子设备长度

返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
void subdev_upgrade_package_choose(unsigned char package_sz,unsigned char*sub_dev_id,unsigned char sub_dev_len);


/*****************************************************************************
函数名称 : qur_subdev_ver_get
功能描述 : wifi模块查询子设备版本号
输入参数 : data_buf：接收到的data部分的首地址
           data_len：接收到的data部分的长度
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
void qur_subdev_ver_get(unsigned char* data_buf,unsigned short data_len);

/*****************************************************************************
函数名称 : subdevice_delete
功能描述 : wifi模块发送关闭入网指令给网关,此函数内获取需要删除
           的子设备id和子设备key，用户需要根据这两条信息自行删除子设备
输入参数 : data_buf：接收到的data部分的首地址
           data_len：接收到的data部分的长度
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
void subdevice_delete(unsigned char* data_buf,unsigned short data_len);


#ifdef WIFI_TEST_ENABLE
/*****************************************************************************
函数名称 : wifi_test_result
功能描述 : wifi功能测试反馈
输入参数 : result:wifi功能测试结果;0:失败/1:成功
           rssi:测试成功表示wifi信号强度/测试失败表示错误类型
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
void wifi_test_result(unsigned char result,unsigned char rssi);
#endif

#ifdef SUPPORT_MCU_FIRM_UPDATE
/*****************************************************************************
函数名称 : mcu_firm_update_handle
功能描述 : MCU进入固件升级模式
输入参数 : value:固件缓冲区
           position:当前数据包在于固件位置
           length:当前固件包长度(固件包长度为0时,表示固件包发送完成)
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
unsigned char mcu_firm_update_handle(const unsigned char value[],unsigned long position,unsigned short length);

/*****************************************************************************
函数名称 : subdev_firm_update_handle
功能描述 : MCU进入子设备升级模式
输入参数 : sub_id_buf:子设备id
           value:固件缓冲区
           position:当前数据包在于固件位置
           length:当前固件包长度(固件包长度为0时,表示固件包发送完成)
返回参数 : 无
使用说明 : MCU需要自行实现该功能
*****************************************************************************/
    unsigned char subdev_firm_update_handle(unsigned char *sub_id_buf,const unsigned char value[],unsigned long position,unsigned short length);
#endif

/*****************************************************************************
函数名称 : dp_download_handle
功能描述 : dp下发处理函数
输入参数 : dpid:DP序号
value:dp数据缓冲区地址
length:dp数据长度
返回参数 : 成功返回:SUCCESS/失败返回:ERRO
使用说明 : 该函数用户不能修改
*****************************************************************************/
unsigned char gw_dp_download_handle(unsigned char dpid,const unsigned char value[], unsigned short length);

/*****************************************************************************
函数名称 : subdev_dp_download_handle
功能描述 : dp下发子设备处理函数
输入参数 : dpid:DP序号
value:dp数据缓冲区地址
length:dp数据长度
返回参数 : 成功返回:SUCCESS/失败返回:ERRO
使用说明 : 该函数用户不能修改
*****************************************************************************/
unsigned char subdev_dp_download_handle(unsigned char dpid,const unsigned char value[], unsigned short length,unsigned char* sub_id);

/*****************************************************************************
函数名称 : get_download_cmd_total
功能描述 : 获取所有dp命令总和
输入参数 : 无
返回参数 : 下发命令总和
使用说明 : 该函数用户不能修改
*****************************************************************************/
unsigned char get_download_cmd_total(void);

#endif

